//控制流平坦化
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const types = require("@babel/types");
const generator = require("@babel/generator").default;

const jscode = `var arr = "3|0|1|2|4".split("|");
var cnt = 0;
while (true) {
    switch (arr[cnt++]) {
        case "0":
            console.log("This is case-block 0");
            continue;
        case "1":
            console.log("This is case-block 1");
            continue;
        case "2":
            console.log("This is case-block 2");
            continue;
        case "3":
            console.log("This is case-block 3");
            continue;
        case "4":
            console.log("This is case-block 4");
            continue;
    }
    break;
}`; //转换为i var b=3;

const ast = parser.parse(jscode);
const visitor = {
    WhileStatement(path){
        const {test,body}=path.node;
        if (!types.isBooleanLiteral(test) || test.value !== true){return;}; //判定while的条件是否为true 不为true
        if (body.body.length ===0 || !types.isSwitchStatement(body.body[0])){return;}; //循环中没有值或者body里第一个值不为switch节点的跳过
        let switch_state=body.body[0]; //把switch节点提取出来
        let {discriminant,cases}=switch_state; // discriminant 代表循环值 cases case 节点
        if (!types.isMemberExpression(discriminant) ||!types.isUpdateExpression(discriminant.property)){return;};
        let arr_name=discriminant.object.name; //获取当前
        let arr=[];
        let all_pre_siblings=path.getAllPrevSiblings(); //获取兄弟节点
        if (all_pre_siblings.length !==2){return;};
        all_pre_siblings.forEach(pre_pth=>{ //提取兄弟节点的数据
            const {declarations}=pre_pth.node;
            let{id,init}=declarations[0]
            if (arr_name==id.name){
                arr=init.callee.object.value.split('|') //并解析出来
            }
            pre_pth.remove()
        })
        let ret_body=[]
        arr.forEach(index=>{
            let case_body=cases[index].consequent //当前case节点下包含的值
            if (types.isContinueStatement(case_body[case_body.length -1])) //跳过continue值
                {case_body.pop()} //把当前值怕抛出去
            ret_body = ret_body.concat(case_body) //链接2个数组 concat
        })
        path.replaceInline(ret_body)

    }
}

traverse(ast, visitor);
console.log(generator(ast)['code'])
